`timescale 1ns / 1ps

`define MEM_SIZE (1024*4)

`define TEST_VECTOR_LEN 138

`define TMS_MEM_PTR_POS 0
`define TDI_MEM_PTR_POS 2048
`define TDO_MEM_PTR_POS 4096

module axi_to_jtag_lm_testbench
	   #
	   (
		   parameter integer C_M_AXI_LITE_ADDR_WIDTH = 32,
		   parameter integer C_M_AXI_LITE_DATA_WIDTH = 32,

		   parameter integer C_LOCAL_MEM_BUFFER_SIZE = `MEM_SIZE,
		   parameter integer C_LOCAL_AXI_MAX_BURST_LENGTH = 256,
		   parameter integer C_LOCAL_AXI_ADDR_WIDTH = 32,
		   parameter integer C_LOCAL_AXI_DATA_WIDTH = 64,

		   parameter integer C_M_JTAG_CLK_FREQUENCY = 100e6,

		   //9 registers, nid 6 bit address
		   parameter integer C_S_AXI_ADDR_WIDTH = 5,
		   parameter integer C_S_AXI_DATA_WIDTH = 32,

		   parameter integer C_VECTOR_LEN = 128,
		   parameter integer C_M_AXI_MAX_BURST_LENGTH = 256,
		   parameter integer C_M_AXI_ADDR_WIDTH = 32,
		   parameter integer C_M_AXI_DATA_WIDTH = 64
	   )
	   ();
wire m_jtag_aclk;
wire m_jtag_aresetn;
wire TCK;
wire TMS;
wire TDI;

wire intr;

reg AXI_LITE_WENABLE;
wire AXI_LITE_WBUSY;
wire AXI_LITE_WERR;

reg AXI_LITE_RENABLE;
wire AXI_LITE_RBUSY;
wire AXI_LITE_RERR;

reg [(C_M_AXI_LITE_ADDR_WIDTH - 1): 0] AXI_LITE_REG_WADDR;
reg [(C_M_AXI_LITE_ADDR_WIDTH - 1): 0] AXI_LITE_REG_RADDR;
reg [1: 0] AXI_LITE_REG_WDW;
reg [1: 0] AXI_LITE_REG_RDW;
reg [(C_M_AXI_LITE_DATA_WIDTH - 1): 0] AXI_LITE_REG_WVAL;
wire [(C_M_AXI_LITE_DATA_WIDTH - 1): 0] AXI_LITE_REG_RVAL;

wire axi_lite_aclk;
wire axi_lite_aresetn;
wire axi_lite_awvalid;
wire axi_lite_awready;
wire [(C_M_AXI_LITE_ADDR_WIDTH - 1) : 0] axi_lite_awaddr;
wire [2 : 0] axi_lite_awprot;
wire axi_lite_wvalid;
wire axi_lite_wready;
wire [C_M_AXI_LITE_DATA_WIDTH - 1 : 0] axi_lite_wdata;
wire [(C_M_AXI_LITE_DATA_WIDTH / 8 - 1) : 0] axi_lite_wstrb;
wire axi_lite_bvalid;
wire axi_lite_bready;
wire [1 : 0] axi_lite_bresp;
wire axi_lite_arvalid;
wire axi_lite_arready;
wire [(C_M_AXI_LITE_ADDR_WIDTH - 1) : 0] axi_lite_araddr;
wire [2 : 0] axi_lite_arprot;
wire axi_lite_rvalid;
wire axi_lite_rready;
wire [C_M_AXI_LITE_DATA_WIDTH - 1 : 0] axi_lite_rdata;
wire [1 : 0] axi_lite_rresp;

template_m_axi_lite
	#
	(
		.C_AXI_ADDR_WIDTH(C_M_AXI_LITE_ADDR_WIDTH),
		.C_AXI_DATA_WIDTH(C_M_AXI_LITE_DATA_WIDTH)
	)
	template_m_axi_lite_inst
	(
		.WENABLE(AXI_LITE_WENABLE),
		.WBUSY(AXI_LITE_WBUSY),
		.WERR(AXI_LITE_WERR),
		.RENABLE(AXI_LITE_RENABLE),
		.RBUSY(AXI_LITE_RBUSY),
		.RERR(AXI_LITE_RERR),
		.REG_WADDR(AXI_LITE_REG_WADDR),
		.REG_RADDR(AXI_LITE_REG_RADDR),
		.REG_WDW(AXI_LITE_REG_WDW),
		.REG_RDW(AXI_LITE_REG_RDW),
		.REG_WVAL(AXI_LITE_REG_WVAL),
		.REG_RVAL(AXI_LITE_REG_RVAL),
		.m_axi_lite_aclk(axi_lite_aclk),
		.m_axi_lite_aresetn(axi_lite_aresetn),
		.m_axi_lite_awvalid(axi_lite_awvalid),
		.m_axi_lite_awready(axi_lite_awready),
		.m_axi_lite_awaddr(axi_lite_awaddr),
		.m_axi_lite_awprot(axi_lite_awprot),
		.m_axi_lite_wvalid(axi_lite_wvalid),
		.m_axi_lite_wready(axi_lite_wready),
		.m_axi_lite_wdata(axi_lite_wdata),
		.m_axi_lite_wstrb(axi_lite_wstrb),
		.m_axi_lite_bvalid(axi_lite_bvalid),
		.m_axi_lite_bready(axi_lite_bready),
		.m_axi_lite_bresp(axi_lite_bresp),
		.m_axi_lite_arvalid(axi_lite_arvalid),
		.m_axi_lite_arready(axi_lite_arready),
		.m_axi_lite_araddr(axi_lite_araddr),
		.m_axi_lite_arprot(axi_lite_arprot),
		.m_axi_lite_rvalid(axi_lite_rvalid),
		.m_axi_lite_rready(axi_lite_rready),
		.m_axi_lite_rdata(axi_lite_rdata),
		.m_axi_lite_rresp(axi_lite_rresp)
	);

wire INTERCONNECT_ACLK ;
wire INTERCONNECT_ARESETN ;
wire S00_AXI_ARESET_OUT_N ;
wire S00_AXI_ACLK ;
wire [0 : 0] S00_AXI_AWID ;
wire [31 : 0] S00_AXI_AWADDR ;
wire [7 : 0] S00_AXI_AWLEN ;
wire [2 : 0] S00_AXI_AWSIZE ;
wire [1 : 0] S00_AXI_AWBURST ;
wire S00_AXI_AWLOCK ;
wire [3 : 0] S00_AXI_AWCACHE ;
wire [2 : 0] S00_AXI_AWPROT ;
wire [3 : 0] S00_AXI_AWQOS ;
wire S00_AXI_AWVALID ;
wire S00_AXI_AWREADY ;
wire [63 : 0] S00_AXI_WDATA ;
wire [7 : 0] S00_AXI_WSTRB ;
wire S00_AXI_WLAST ;
wire S00_AXI_WVALID ;
wire S00_AXI_WREADY ;
wire [0 : 0] S00_AXI_BID ;
wire [1 : 0] S00_AXI_BRESP ;
wire S00_AXI_BVALID ;
wire S00_AXI_BREADY ;
wire [0 : 0] S00_AXI_ARID ;
wire [31 : 0] S00_AXI_ARADDR ;
wire [7 : 0] S00_AXI_ARLEN ;
wire [2 : 0] S00_AXI_ARSIZE ;
wire [1 : 0] S00_AXI_ARBURST ;
wire S00_AXI_ARLOCK ;
wire [3 : 0] S00_AXI_ARCACHE ;
wire [2 : 0] S00_AXI_ARPROT ;
wire [3 : 0] S00_AXI_ARQOS ;
wire S00_AXI_ARVALID ;
wire S00_AXI_ARREADY ;
wire [0 : 0] S00_AXI_RID ;
wire [63 : 0] S00_AXI_RDATA ;
wire [1 : 0] S00_AXI_RRESP ;
wire S00_AXI_RLAST ;
wire S00_AXI_RVALID ;
wire S00_AXI_RREADY ;
wire S01_AXI_ARESET_OUT_N ;
wire S01_AXI_ACLK ;
wire [0 : 0] S01_AXI_AWID ;
wire [31 : 0] S01_AXI_AWADDR ;
wire [7 : 0] S01_AXI_AWLEN ;
wire [2 : 0] S01_AXI_AWSIZE ;
wire [1 : 0] S01_AXI_AWBURST ;
wire S01_AXI_AWLOCK ;
wire [3 : 0] S01_AXI_AWCACHE ;
wire [2 : 0] S01_AXI_AWPROT ;
wire [3 : 0] S01_AXI_AWQOS ;
wire S01_AXI_AWVALID ;
wire S01_AXI_AWREADY ;
wire [63 : 0] S01_AXI_WDATA ;
wire [7 : 0] S01_AXI_WSTRB ;
wire S01_AXI_WLAST ;
wire S01_AXI_WVALID ;
wire S01_AXI_WREADY ;
wire [0 : 0] S01_AXI_BID ;
wire [1 : 0] S01_AXI_BRESP ;
wire S01_AXI_BVALID ;
wire S01_AXI_BREADY ;
wire [0 : 0] S01_AXI_ARID ;
wire [31 : 0] S01_AXI_ARADDR ;
wire [7 : 0] S01_AXI_ARLEN ;
wire [2 : 0] S01_AXI_ARSIZE ;
wire [1 : 0] S01_AXI_ARBURST ;
wire S01_AXI_ARLOCK ;
wire [3 : 0] S01_AXI_ARCACHE ;
wire [2 : 0] S01_AXI_ARPROT ;
wire [3 : 0] S01_AXI_ARQOS ;
wire S01_AXI_ARVALID ;
wire S01_AXI_ARREADY ;
wire [0 : 0] S01_AXI_RID ;
wire [63 : 0] S01_AXI_RDATA ;
wire [1 : 0] S01_AXI_RRESP ;
wire S01_AXI_RLAST ;
wire S01_AXI_RVALID ;
wire S01_AXI_RREADY ;
wire M00_AXI_ARESET_OUT_N ;
wire M00_AXI_ACLK ;
wire [3 : 0] M00_AXI_AWID ;
wire [31 : 0] M00_AXI_AWADDR ;
wire [7 : 0] M00_AXI_AWLEN ;
wire [2 : 0] M00_AXI_AWSIZE ;
wire [1 : 0] M00_AXI_AWBURST ;
wire M00_AXI_AWLOCK ;
wire [3 : 0] M00_AXI_AWCACHE ;
wire [2 : 0] M00_AXI_AWPROT ;
wire [3 : 0] M00_AXI_AWQOS ;
wire M00_AXI_AWVALID ;
wire M00_AXI_AWREADY ;
wire [63 : 0] M00_AXI_WDATA ;
wire [7 : 0] M00_AXI_WSTRB ;
wire M00_AXI_WLAST ;
wire M00_AXI_WVALID ;
wire M00_AXI_WREADY ;
wire [3 : 0] M00_AXI_BID ;
wire [1 : 0] M00_AXI_BRESP ;
wire M00_AXI_BVALID ;
wire M00_AXI_BREADY ;
wire [3 : 0] M00_AXI_ARID ;
wire [31 : 0] M00_AXI_ARADDR ;
wire [7 : 0] M00_AXI_ARLEN ;
wire [2 : 0] M00_AXI_ARSIZE ;
wire [1 : 0] M00_AXI_ARBURST ;
wire M00_AXI_ARLOCK ;
wire [3 : 0] M00_AXI_ARCACHE ;
wire [2 : 0] M00_AXI_ARPROT ;
wire [3 : 0] M00_AXI_ARQOS ;
wire M00_AXI_ARVALID ;
wire M00_AXI_ARREADY ;
wire [3 : 0] M00_AXI_RID ;
wire [63 : 0] M00_AXI_RDATA ;
wire [1 : 0] M00_AXI_RRESP ;
wire M00_AXI_RLAST ;
wire M00_AXI_RVALID ;
wire M00_AXI_RREADY ;

axi_interconnect axi_interconnect_inst (
					 .INTERCONNECT_ACLK(INTERCONNECT_ACLK),
					 .INTERCONNECT_ARESETN(INTERCONNECT_ARESETN),
					 .S00_AXI_ARESET_OUT_N(S00_AXI_ARESET_OUT_N),
					 .S00_AXI_ACLK(S00_AXI_ACLK),
					 .S00_AXI_AWID(S00_AXI_AWID),
					 .S00_AXI_AWADDR(S00_AXI_AWADDR),
					 .S00_AXI_AWLEN(S00_AXI_AWLEN),
					 .S00_AXI_AWSIZE(S00_AXI_AWSIZE),
					 .S00_AXI_AWBURST(S00_AXI_AWBURST),
					 .S00_AXI_AWLOCK(S00_AXI_AWLOCK),
					 .S00_AXI_AWCACHE(S00_AXI_AWCACHE),
					 .S00_AXI_AWPROT(S00_AXI_AWPROT),
					 .S00_AXI_AWQOS(S00_AXI_AWQOS),
					 .S00_AXI_AWVALID(S00_AXI_AWVALID),
					 .S00_AXI_AWREADY(S00_AXI_AWREADY),
					 .S00_AXI_WDATA(S00_AXI_WDATA),
					 .S00_AXI_WSTRB(S00_AXI_WSTRB),
					 .S00_AXI_WLAST(S00_AXI_WLAST),
					 .S00_AXI_WVALID(S00_AXI_WVALID),
					 .S00_AXI_WREADY(S00_AXI_WREADY),
					 .S00_AXI_BID(S00_AXI_BID),
					 .S00_AXI_BRESP(S00_AXI_BRESP),
					 .S00_AXI_BVALID(S00_AXI_BVALID),
					 .S00_AXI_BREADY(S00_AXI_BREADY),
					 .S00_AXI_ARID(S00_AXI_ARID),
					 .S00_AXI_ARADDR(S00_AXI_ARADDR),
					 .S00_AXI_ARLEN(S00_AXI_ARLEN),
					 .S00_AXI_ARSIZE(S00_AXI_ARSIZE),
					 .S00_AXI_ARBURST(S00_AXI_ARBURST),
					 .S00_AXI_ARLOCK(S00_AXI_ARLOCK),
					 .S00_AXI_ARCACHE(S00_AXI_ARCACHE),
					 .S00_AXI_ARPROT(S00_AXI_ARPROT),
					 .S00_AXI_ARQOS(S00_AXI_ARQOS),
					 .S00_AXI_ARVALID(S00_AXI_ARVALID),
					 .S00_AXI_ARREADY(S00_AXI_ARREADY),
					 .S00_AXI_RID(S00_AXI_RID),
					 .S00_AXI_RDATA(S00_AXI_RDATA),
					 .S00_AXI_RRESP(S00_AXI_RRESP),
					 .S00_AXI_RLAST(S00_AXI_RLAST),
					 .S00_AXI_RVALID(S00_AXI_RVALID),
					 .S00_AXI_RREADY(S00_AXI_RREADY),
					 .S01_AXI_ARESET_OUT_N(S01_AXI_ARESET_OUT_N),
					 .S01_AXI_ACLK(S01_AXI_ACLK),
					 .S01_AXI_AWID(S01_AXI_AWID),
					 .S01_AXI_AWADDR(S01_AXI_AWADDR),
					 .S01_AXI_AWLEN(S01_AXI_AWLEN),
					 .S01_AXI_AWSIZE(S01_AXI_AWSIZE),
					 .S01_AXI_AWBURST(S01_AXI_AWBURST),
					 .S01_AXI_AWLOCK(S01_AXI_AWLOCK),
					 .S01_AXI_AWCACHE(S01_AXI_AWCACHE),
					 .S01_AXI_AWPROT(S01_AXI_AWPROT),
					 .S01_AXI_AWQOS(S01_AXI_AWQOS),
					 .S01_AXI_AWVALID(S01_AXI_AWVALID),
					 .S01_AXI_AWREADY(S01_AXI_AWREADY),
					 .S01_AXI_WDATA(S01_AXI_WDATA),
					 .S01_AXI_WSTRB(S01_AXI_WSTRB),
					 .S01_AXI_WLAST(S01_AXI_WLAST),
					 .S01_AXI_WVALID(S01_AXI_WVALID),
					 .S01_AXI_WREADY(S01_AXI_WREADY),
					 .S01_AXI_BID(S01_AXI_BID),
					 .S01_AXI_BRESP(S01_AXI_BRESP),
					 .S01_AXI_BVALID(S01_AXI_BVALID),
					 .S01_AXI_BREADY(S01_AXI_BREADY),
					 .S01_AXI_ARID(S01_AXI_ARID),
					 .S01_AXI_ARADDR(S01_AXI_ARADDR),
					 .S01_AXI_ARLEN(S01_AXI_ARLEN),
					 .S01_AXI_ARSIZE(S01_AXI_ARSIZE),
					 .S01_AXI_ARBURST(S01_AXI_ARBURST),
					 .S01_AXI_ARLOCK(S01_AXI_ARLOCK),
					 .S01_AXI_ARCACHE(S01_AXI_ARCACHE),
					 .S01_AXI_ARPROT(S01_AXI_ARPROT),
					 .S01_AXI_ARQOS(S01_AXI_ARQOS),
					 .S01_AXI_ARVALID(S01_AXI_ARVALID),
					 .S01_AXI_ARREADY(S01_AXI_ARREADY),
					 .S01_AXI_RID(S01_AXI_RID),
					 .S01_AXI_RDATA(S01_AXI_RDATA),
					 .S01_AXI_RRESP(S01_AXI_RRESP),
					 .S01_AXI_RLAST(S01_AXI_RLAST),
					 .S01_AXI_RVALID(S01_AXI_RVALID),
					 .S01_AXI_RREADY(S01_AXI_RREADY),
					 .M00_AXI_ARESET_OUT_N(M00_AXI_ARESET_OUT_N),
					 .M00_AXI_ACLK(M00_AXI_ACLK),
					 .M00_AXI_AWID(M00_AXI_AWID),
					 .M00_AXI_AWADDR(M00_AXI_AWADDR),
					 .M00_AXI_AWLEN(M00_AXI_AWLEN),
					 .M00_AXI_AWSIZE(M00_AXI_AWSIZE),
					 .M00_AXI_AWBURST(M00_AXI_AWBURST),
					 .M00_AXI_AWLOCK(M00_AXI_AWLOCK),
					 .M00_AXI_AWCACHE(M00_AXI_AWCACHE),
					 .M00_AXI_AWPROT(M00_AXI_AWPROT),
					 .M00_AXI_AWQOS(M00_AXI_AWQOS),
					 .M00_AXI_AWVALID(M00_AXI_AWVALID),
					 .M00_AXI_AWREADY(M00_AXI_AWREADY),
					 .M00_AXI_WDATA(M00_AXI_WDATA),
					 .M00_AXI_WSTRB(M00_AXI_WSTRB),
					 .M00_AXI_WLAST(M00_AXI_WLAST),
					 .M00_AXI_WVALID(M00_AXI_WVALID),
					 .M00_AXI_WREADY(M00_AXI_WREADY),
					 .M00_AXI_BID(M00_AXI_BID),
					 .M00_AXI_BRESP(M00_AXI_BRESP),
					 .M00_AXI_BVALID(M00_AXI_BVALID),
					 .M00_AXI_BREADY(M00_AXI_BREADY),
					 .M00_AXI_ARID(M00_AXI_ARID),
					 .M00_AXI_ARADDR(M00_AXI_ARADDR),
					 .M00_AXI_ARLEN(M00_AXI_ARLEN),
					 .M00_AXI_ARSIZE(M00_AXI_ARSIZE),
					 .M00_AXI_ARBURST(M00_AXI_ARBURST),
					 .M00_AXI_ARLOCK(M00_AXI_ARLOCK),
					 .M00_AXI_ARCACHE(M00_AXI_ARCACHE),
					 .M00_AXI_ARPROT(M00_AXI_ARPROT),
					 .M00_AXI_ARQOS(M00_AXI_ARQOS),
					 .M00_AXI_ARVALID(M00_AXI_ARVALID),
					 .M00_AXI_ARREADY(M00_AXI_ARREADY),
					 .M00_AXI_RID(M00_AXI_RID),
					 .M00_AXI_RDATA(M00_AXI_RDATA),
					 .M00_AXI_RRESP(M00_AXI_RRESP),
					 .M00_AXI_RLAST(M00_AXI_RLAST),
					 .M00_AXI_RVALID(M00_AXI_RVALID),
					 .M00_AXI_RREADY(M00_AXI_RREADY)
				 );

axi_to_jtag_lm
	#
	(
		.C_JTAG_TYPE(0),
		.C_M_JTAG_CLK_FREQUENCY(C_M_JTAG_CLK_FREQUENCY),

		//9 registers, nid 6 bit address
		.C_S_AXI_ADDR_WIDTH(C_S_AXI_ADDR_WIDTH),
		.C_S_AXI_DATA_WIDTH(C_S_AXI_DATA_WIDTH),

		.C_VECTOR_LEN(C_VECTOR_LEN),
		.C_M_AXI_MAX_BURST_LENGTH(C_M_AXI_MAX_BURST_LENGTH),
		.C_M_AXI_ADDR_WIDTH(C_M_AXI_ADDR_WIDTH),
		.C_M_AXI_DATA_WIDTH(C_M_AXI_DATA_WIDTH)
	)
	axi_to_jtag_lm_inst
	(
		.s_axi_lite_aclk(axi_lite_aclk),
		.s_axi_lite_aresetn(axi_lite_aresetn),
		.s_axi_lite_awvalid(axi_lite_awvalid),
		.s_axi_lite_awready(axi_lite_awready),
		.s_axi_lite_awaddr(axi_lite_awaddr),
		.s_axi_lite_awprot(axi_lite_awprot),
		.s_axi_lite_wvalid(axi_lite_wvalid),
		.s_axi_lite_wready(axi_lite_wready),
		.s_axi_lite_wdata(axi_lite_wdata),
		.s_axi_lite_wstrb(axi_lite_wstrb),
		.s_axi_lite_bvalid(axi_lite_bvalid),
		.s_axi_lite_bready(axi_lite_bready),
		.s_axi_lite_bresp(axi_lite_bresp),
		.s_axi_lite_arvalid(axi_lite_arvalid),
		.s_axi_lite_arready(axi_lite_arready),
		.s_axi_lite_araddr(axi_lite_araddr),
		.s_axi_lite_arprot(axi_lite_arprot),
		.s_axi_lite_rvalid(axi_lite_rvalid),
		.s_axi_lite_rready(axi_lite_rready),
		.s_axi_lite_rdata(axi_lite_rdata),
		.s_axi_lite_rresp(axi_lite_rresp),

		.m_axi_aclk(S00_AXI_ACLK),
		.m_axi_aresetn(S00_AXI_ARESET_OUT_N),
		.m_axi_awaddr(S00_AXI_AWADDR),
		.m_axi_awlen(S00_AXI_AWLEN),
		.m_axi_awsize(S00_AXI_AWSIZE),
		.m_axi_awburst(S00_AXI_AWBURST),
		.m_axi_awlock(S00_AXI_AWLOCK),
		.m_axi_awcache(S00_AXI_AWCACHE),
		.m_axi_awprot(S00_AXI_AWPROT),
		.m_axi_awqos(S00_AXI_AWQOS),
		.m_axi_awvalid(S00_AXI_AWVALID),
		.m_axi_awready(S00_AXI_AWREADY),
		.m_axi_wdata(S00_AXI_WDATA),
		.m_axi_wstrb(S00_AXI_WSTRB),
		.m_axi_wlast(S00_AXI_WLAST),
		.m_axi_wvalid(S00_AXI_WVALID),
		.m_axi_wready(S00_AXI_WREADY),
		.m_axi_bresp(S00_AXI_BRESP),
		.m_axi_bvalid(S00_AXI_BVALID),
		.m_axi_bready(S00_AXI_BREADY),
		.m_axi_araddr(S00_AXI_ARADDR),
		.m_axi_arlen(S00_AXI_ARLEN),
		.m_axi_arsize(S00_AXI_ARSIZE),
		.m_axi_arburst(S00_AXI_ARBURST),
		.m_axi_arlock(S00_AXI_ARLOCK),
		.m_axi_arcache(S00_AXI_ARCACHE),
		.m_axi_arprot(S00_AXI_ARPROT),
		.m_axi_arqos(S00_AXI_ARQOS),
		.m_axi_arvalid(S00_AXI_ARVALID),
		.m_axi_arready(S00_AXI_ARREADY),
		.m_axi_rdata(S00_AXI_RDATA),
		.m_axi_rresp(S00_AXI_RRESP),
		.m_axi_rlast(S00_AXI_RLAST),
		.m_axi_rvalid(S00_AXI_RVALID),
		.m_axi_rready(S00_AXI_RREADY),

		.m_jtag_aclk(m_jtag_aclk),
		.m_jtag_aresetn(m_jtag_aresetn),
		.m_tck(TCK),
		.m_tms(TMS),
		.m_tdi(TDI),
		.m_tdo(TDI),
		
		.intr(intr)
	);

blk_mem_gen blk_mem_gen_inst (
				.s_aclk(M00_AXI_ACLK),                         // input wire s_aclk
				.s_aresetn(M00_AXI_ARESET_OUT_N),                   // input wire s_aresetn
				.s_axi_awid(M00_AXI_AWID),                 // input wire [3 : 0] s_axi_awid
				.s_axi_awaddr(M00_AXI_AWADDR),             // input wire [31 : 0] s_axi_awaddr
				.s_axi_awlen(M00_AXI_AWLEN),               // input wire [7 : 0] s_axi_awlen
				.s_axi_awsize(M00_AXI_AWSIZE),             // input wire [2 : 0] s_axi_awsize
				.s_axi_awburst(M00_AXI_AWBURST),           // input wire [1 : 0] s_axi_awburst
				.s_axi_awvalid(M00_AXI_AWVALID),           // input wire s_axi_awvalid
				.s_axi_awready(M00_AXI_AWREADY),           // output wire s_axi_awready
				.s_axi_wdata(M00_AXI_WDATA),               // input wire [63 : 0] s_axi_wdata
				.s_axi_wstrb(M00_AXI_WSTRB),               // input wire [7 : 0] s_axi_wstrb
				.s_axi_wlast(M00_AXI_WLAST),               // input wire s_axi_wlast
				.s_axi_wvalid(M00_AXI_WVALID),             // input wire s_axi_wvalid
				.s_axi_wready(M00_AXI_WREADY),             // output wire s_axi_wready
				.s_axi_bid(M00_AXI_BID),                   // output wire [3 : 0] s_axi_bid
				.s_axi_bresp(M00_AXI_BRESP),               // output wire [1 : 0] s_axi_bresp
				.s_axi_bvalid(M00_AXI_BVALID),             // output wire s_axi_bvalid
				.s_axi_bready(M00_AXI_BREADY),             // input wire s_axi_bready
				.s_axi_arid(M00_AXI_ARID),                 // input wire [3 : 0] s_axi_arid
				.s_axi_araddr(M00_AXI_ARADDR),             // input wire [31 : 0] s_axi_araddr
				.s_axi_arlen(M00_AXI_ARLEN),               // input wire [7 : 0] s_axi_arlen
				.s_axi_arsize(M00_AXI_ARSIZE),             // input wire [2 : 0] s_axi_arsize
				.s_axi_arburst(M00_AXI_ARBURST),           // input wire [1 : 0] s_axi_arburst
				.s_axi_arvalid(M00_AXI_ARVALID),           // input wire s_axi_arvalid
				.s_axi_arready(M00_AXI_ARREADY),           // output wire s_axi_arready
				.s_axi_rid(M00_AXI_RID),                   // output wire [3 : 0] s_axi_rid
				.s_axi_rdata(M00_AXI_RDATA),               // output wire [63 : 0] s_axi_rdata
				.s_axi_rresp(M00_AXI_RRESP),               // output wire [1 : 0] s_axi_rresp
				.s_axi_rlast(M00_AXI_RLAST),               // output wire s_axi_rlast
				.s_axi_rvalid(M00_AXI_RVALID),             // output wire s_axi_rvalid
				.s_axi_rready(M00_AXI_RREADY)    // input wire s_axi_rready
			);

reg AXI_WENABLE;
wire AXI_WBUSY;
wire AXI_WERR;
reg AXI_RENABLE;
wire AXI_RBUSY;
wire AXI_RERR;

reg [(C_LOCAL_AXI_ADDR_WIDTH - 1): 0] AXI_MEM_WADDR_BASE;
reg [(C_LOCAL_AXI_ADDR_WIDTH - 1): 0] AXI_MEM_RADDR_BASE;
reg [31: 0] AXI_MEM_WLEN;
reg [31: 0] AXI_MEM_RLEN;
reg [(8 * C_LOCAL_MEM_BUFFER_SIZE - 1): 0] AXI_MEM_WVAL;
wire [(8 * C_LOCAL_MEM_BUFFER_SIZE - 1): 0] AXI_MEM_RVAL;

template_m_axi_s
	#
	(
		.C_MEM_BUFFER_SIZE(C_LOCAL_MEM_BUFFER_SIZE),
		.C_AXI_MAX_BURST_LENGTH(C_LOCAL_AXI_MAX_BURST_LENGTH),
		.C_AXI_ADDR_WIDTH(C_LOCAL_AXI_ADDR_WIDTH),
		.C_AXI_DATA_WIDTH(C_LOCAL_AXI_DATA_WIDTH)
	)
	template_m_axi_s_inst
	(
		.WENABLE(AXI_WENABLE),
		.WBUSY(AXI_WBUSY),
		.WERR(AXI_WERR),
		.RENABLE(AXI_RENABLE),
		.RBUSY(AXI_RBUSY),
		.RERR(AXI_RERR),

		.MEM_WADDR_BASE(AXI_MEM_WADDR_BASE),
		.MEM_RADDR_BASE(AXI_MEM_RADDR_BASE),
		.MEM_WLEN(AXI_MEM_WLEN),
		.MEM_RLEN(AXI_MEM_RLEN),
		.MEM_WVAL(AXI_MEM_WVAL),
		.MEM_RVAL(AXI_MEM_RVAL),

		.m_axi_aclk(S01_AXI_ACLK),
		.m_axi_aresetn(S01_AXI_ARESET_OUT_N),
		.m_axi_awaddr(S01_AXI_AWADDR),
		.m_axi_awlen(S01_AXI_AWLEN),
		.m_axi_awsize(S01_AXI_AWSIZE),
		.m_axi_awburst(S01_AXI_AWBURST),
		.m_axi_awlock(S01_AXI_AWLOCK),
		.m_axi_awcache(S01_AXI_AWCACHE),
		.m_axi_awprot(S01_AXI_AWPROT),
		.m_axi_awqos(S01_AXI_AWQOS),
		.m_axi_awvalid(S01_AXI_AWVALID),
		.m_axi_awready(S01_AXI_AWREADY),
		.m_axi_wdata(S01_AXI_WDATA),
		.m_axi_wstrb(S01_AXI_WSTRB),
		.m_axi_wlast(S01_AXI_WLAST),
		.m_axi_wvalid(S01_AXI_WVALID),
		.m_axi_wready(S01_AXI_WREADY),
		.m_axi_bresp(S01_AXI_BRESP),
		.m_axi_bvalid(S01_AXI_BVALID),
		.m_axi_bready(S01_AXI_BREADY),
		.m_axi_araddr(S01_AXI_ARADDR),
		.m_axi_arlen(S01_AXI_ARLEN),
		.m_axi_arsize(S01_AXI_ARSIZE),
		.m_axi_arburst(S01_AXI_ARBURST),
		.m_axi_arlock(S01_AXI_ARLOCK),
		.m_axi_arcache(S01_AXI_ARCACHE),
		.m_axi_arprot(S01_AXI_ARPROT),
		.m_axi_arqos(S01_AXI_ARQOS),
		.m_axi_arvalid(S01_AXI_ARVALID),
		.m_axi_arready(S01_AXI_ARREADY),
		.m_axi_rdata(S01_AXI_RDATA),
		.m_axi_rresp(S01_AXI_RRESP),
		.m_axi_rlast(S01_AXI_RLAST),
		.m_axi_rvalid(S01_AXI_RVALID),
		.m_axi_rready(S01_AXI_RREADY)
	);

reg global_clk;
reg global_nrst;

always #(5) global_clk = ~global_clk;

assign m_jtag_aclk = global_clk;
assign axi_lite_aclk = global_clk;
assign INTERCONNECT_ACLK = global_clk;
assign S00_AXI_ACLK = global_clk;
assign S01_AXI_ACLK = global_clk;
assign M00_AXI_ACLK = global_clk;

assign m_jtag_aresetn = global_nrst;
assign axi_lite_aresetn = global_nrst;
assign INTERCONNECT_ARESETN = global_nrst;

initial
begin
	global_clk <= 0;
	global_nrst <= 0;

	#50;
	global_nrst <= 1;
end

integer i;

initial
begin
	AXI_LITE_WENABLE <= 0;
	AXI_LITE_RENABLE <= 0;
	AXI_LITE_REG_WADDR <= 0;
	AXI_LITE_REG_RADDR <= 0;
	AXI_LITE_REG_WDW <= 0;
	AXI_LITE_REG_RDW <= 0;
	AXI_LITE_REG_WVAL <= 0;

	AXI_WENABLE <= 0;
	AXI_RENABLE <= 0;
	AXI_MEM_WADDR_BASE <= 0;
	AXI_MEM_RADDR_BASE <= 0;
	AXI_MEM_WLEN <= 0;
	AXI_MEM_RLEN <= 0;
	AXI_MEM_WVAL <= 0;

	#300;

	for (i = 0;i < (`TEST_VECTOR_LEN + 7) / 8;i = i + 1)
	begin
		AXI_MEM_WVAL[(8 * i) + : 8] <= i + 'h01;
	end

	AXI_MEM_WADDR_BASE = `TMS_MEM_PTR_POS;
	AXI_MEM_WLEN = (`TEST_VECTOR_LEN + 7) / 8;
	AXI_WENABLE <= 1;
	@(~AXI_WBUSY);
	@(AXI_WBUSY);
	AXI_WENABLE = 0;

	#20;

	for (i = 0;i < (`TEST_VECTOR_LEN + 7) / 8;i = i + 1)
	begin
		AXI_MEM_WVAL[(8 * i) + : 8] <= i + 'h11;
	end

	AXI_MEM_WADDR_BASE = `TDI_MEM_PTR_POS;
	AXI_MEM_WLEN = (`TEST_VECTOR_LEN + 7) / 8;
	AXI_WENABLE <= 1;
	@(~AXI_WBUSY);
	@(AXI_WBUSY);
	AXI_WENABLE = 0;

	#20;
	AXI_LITE_REG_WADDR <= 'h08;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= 'd429496730;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;

	#20;
	AXI_LITE_REG_WADDR <= 'h04;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= `TEST_VECTOR_LEN;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;

	#20;
	AXI_LITE_REG_WADDR <= 'h0C;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= `TMS_MEM_PTR_POS;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;

	#20;
	AXI_LITE_REG_WADDR <= 'h10;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= `TDI_MEM_PTR_POS;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;
	
	#20;
	AXI_LITE_REG_WADDR <= 'h14;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= `TDO_MEM_PTR_POS;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;

	#20;
	AXI_LITE_REG_WADDR <= 'h0;
	AXI_LITE_REG_WDW <= 2;
	AXI_LITE_REG_WVAL <= 'h3;
	AXI_LITE_WENABLE <= 1;
	@(~AXI_LITE_WBUSY);
	@(AXI_LITE_WBUSY);
	AXI_LITE_WENABLE <= 0;


end

endmodule